package handlers

import (
	"encoding/json"
	"fmt"
	"net/http"
	"strconv"
	"sync"
	"werewolf/core"

	"github.com/gorilla/websocket"
)

var upgrader = websocket.Upgrader{
	CheckOrigin: func(r *http.Request) bool {
		return true // Allow all origins for simplicity
	},
}

var clients = make(map[*websocket.Conn]bool) // Connected clients
var mu sync.Mutex                            // Mutex to protect the clients map
type msg struct {
	RmNo      string `json:"RmNo"`
	Speaktype int    `json:"speaktype"`
	User      int    `json:"user"`
	Type      string `json:"type"`
	Content   string `json:"content"`
}

var speaktype [101]int //标识当前阶段的发言类型，1为正常发言，2为遗言发言，3为夜晚狼人发言

func WebSocketHandler(w http.ResponseWriter, r *http.Request) {
	//   聊天室
	conn, err := upgrader.Upgrade(w, r, nil)
	if err != nil {
		fmt.Println("Error during connection upgrade:", err)
		return
	}
	defer conn.Close()

	mu.Lock()
	clients[conn] = true // Add new client
	mu.Unlock()

	for {
		var msgBuffer msg
		err := conn.ReadJSON(&msgBuffer)
		if err != nil {
			fmt.Println("Error reading message:", err.Error())
			mu.Lock()
			delete(clients, conn) // Remove client on error
			mu.Unlock()
			break
		}

		User := msgBuffer.User
		RmNo, _ := strconv.Atoi(msgBuffer.RmNo)

		handle, err := core.Connection()
		if err != nil {
			fmt.Println("Error connecting to database:", err)
			return
		}
		defer handle.Close()

		switch msgBuffer.Type {
		case "Speak":
			Speaking(User, RmNo, msgBuffer.Content, speaktype[RmNo])
		case "Start":
			_, err := handle.Exec("UPDATE running SET boomable = 1 WHERE RmNo = ?", RmNo)
			if err != nil {
				fmt.Println("Error updating boomable status:", err)
				return
			}

			broadcastMessage("现在开始轮流进行发言, 每人发言时间为1分钟", "system")

		case "End":
			fmt.Println("END CHAT")

			//判断本局游戏是否有ai参与且ai是否存活，如果有，则收集本局玩家的所有发言信息，并将发言信息告知ai
			//判断
			//汇集信息，告知ai玩家
			var exists bool
			err = handle.QueryRow("SELECT EXISTS(SELECT 1 FROM ai_info WHERE RmNo = ?)", RmNo).Scan(&exists)
			if err != nil {
				http.Error(w, "Database query failed: "+err.Error(), http.StatusInternalServerError)
				return
			}

			if exists {
				//当前对局存在ai玩家，进行下一步判断，判断ai是否已经死亡
				survival := 0
				err = handle.QueryRow("SELECT Survival FROM player WHERE Role =1 AND RmNo = ?", RmNo).Scan(&survival)
				if err != nil {
					http.Error(w, "Database query failed: "+err.Error(), http.StatusInternalServerError)
				}
				if survival == 1 {
					//此局有ai玩家参与，并且在发言结束之后ai玩家依然存活
					rows, err := handle.Query("SELECT PlayerInt,Speech From Player_Speech WHERE RmNo = ?", RmNo)
					if err != nil {
						fmt.Println("Error querying player speech:", err)
						return
					}
					playerspeech := make(map[int]string)
					for rows.Next() {
						var PlayerInt int
						var Speech string

						// 扫描每一行的结果到变量中
						err := rows.Scan(&PlayerInt, &Speech)
						if err != nil {
							fmt.Println("Error scanning player speech:", err)
						}

						// 将结果存储到 map 中
						playerspeech[PlayerInt] = Speech
					}

					rm := otherPlayersStatements(RmNo, playerspeech) //告知ai其他玩家的发言信息
					if !rm {
						fmt.Println("Error informing other players")
						//对成功告知的处理
					}

				}

			}
			_, err = handle.Exec("DELETE FROM Player_Speech WHERE RmNo = ?", RmNo) //每一轮发言结束后删除本轮发言
			if err != nil {
				fmt.Println("Error deleting player speech:", err)
				return
			}

			_, err = handle.Exec("UPDATE player SET vote = 0 WHERE RmNo = ?", RmNo)
			if err != nil {
				fmt.Println("Error updating vote status:", err)
				return
			}

			_, err = handle.Exec("UPDATE running SET voting = 1 WHERE RmNo = ?", RmNo)
			if err != nil {
				fmt.Println("Error updating voting status:", err)
				return
			}

			broadcastMessage("现在结束发言, 进入1分钟投票阶段", "system")

			//发言结束，询问ai玩家的投票结果

		case "Turn":
			//在此处每次改变对应房间的发言类型
			speaktype[RmNo] = msgBuffer.Speaktype
			handle, err := core.Connection()
			if err != nil {
				fmt.Println("Error connecting to database:", err)
				return
			}
			defer handle.Close()

			_, err = handle.Exec("UPDATE running SET speaking = ? WHERE RmNo = ?", User, RmNo)
			if err != nil {
				fmt.Println("Error updating speaking status:", err)
				return
			}

			broadcastMessage(fmt.Sprintf("现在轮到玩家%d发言", User), "system")

			//此处补充检测是否轮到ai发言，检测本局是否有ai玩家参与，并根据user判断当前是否轮到ai玩家发言（正常发言与遗言发表相同）
			var exists bool
			err = handle.QueryRow("SELECT EXISTS(SELECT 1 FROM Ai_info WHERE RmNo = ?)", RmNo).Scan(&exists)
			if err != nil {
				http.Error(w, "Database query failed: "+err.Error(), http.StatusInternalServerError)
				return
			} //判断是否有ai玩家参与
			if exists {
				//如果轮到ai发言
				if User == 1 { //1为ai玩家编号
					//判断当前房间发言阶段，以此区分ai发表的是正常发言还是遗言
					if speaktype[RmNo] == 1 {
						stament := speak(RmNo)
						if stament != "" {
							Speaking(1, RmNo, stament, speaktype[RmNo]) //轮到ai玩家进行发言，调用speaking函数输出发言内容
						}
						//正常发言阶段
					} else if speaktype[RmNo] == 2 {
						stament := lastWords(RmNo)
						if stament != "" {
							Speaking(1, RmNo, stament, speaktype[RmNo]) //轮到ai玩家进行遗言发表，调用speaking函数输出发言内容
						}

					}

				}

			}

		case "w":
			broadcastMessage(fmt.Sprintf("狼人阵营玩家%d发言: %s", msgBuffer.User, msgBuffer.Content), "w")
			handle, err := core.Connection()
			if err != nil {
				http.Error(w, "Connection failed: "+err.Error(), http.StatusInternalServerError)
				return
			}
			defer handle.Close()
			role := ""
			roleint := 0

			var exists bool
			err = handle.QueryRow("SELECT EXISTS(SELECT 1 FROM ai_info WHERE RmNo = ?)", RmNo).Scan(&exists)
			if err != nil {
				http.Error(w, "Database query failed: "+err.Error(), http.StatusInternalServerError)
				return
			}
			if exists {
				err = handle.QueryRow("SELECT Role,RoleInt FROM ai_info WHERE RmNo = ?", RmNo).Scan(&role, &roleint)
				if err != nil {
					http.Error(w, "Database query failed: "+err.Error(), http.StatusInternalServerError)
					return
				}
				if role == "w" || role == "w-king" || role == "w-knight" || role == "w-devil" {
					aiwords := wolveTalk(RmNo, msgBuffer.User, msgBuffer.Content, 2) //告知ai狼队友发言的内容
					if aiwords != "" {
						broadcastMessage(fmt.Sprintf("玩家%d发言: %s", 1, aiwords), "w") //如ai有回复，则将ai的回复广播
					}
				}
			}
			//狼人队友发言，将发言信息告知ai并返回ai的回复
			//检测本局游戏是否有ai玩家参与并且ai玩家是否存活且是否为狼人阵营

		default:
			broadcastMessage(msgBuffer.Content, msgBuffer.Type)
		}

	}
}

//此处实现接受其他玩家的发言和传输ai的发言

func Speaking(user int, rm int, content string, speaktype int) {
	//ai存在时检测发言类型，1则存入数据库，2、3则直接告知ai
	handle, err := core.Connection()
	if err != nil {
		fmt.Println("Error connecting to database:", err)
		return
	}
	defer handle.Close()

	tx, err := handle.Begin()
	if err != nil {
		fmt.Println("Error starting transaction:", err)
		return
	}
	defer tx.Commit()

	var speaking int
	err = tx.QueryRow("SELECT speaking FROM running WHERE RmNo = ? ", rm).Scan(&speaking)
	if err != nil {
		fmt.Println("Error getting speaking status:", err)
		return
	}

	if speaking == user {
		//玩家准许发言，若ai玩家存在且存活玩家进行发言并把发言传入数据库中
		var exists bool
		err = handle.QueryRow("SELECT EXISTS(SELECT 1 FROM ai_info WHERE RmNo = ?)", rm).Scan(&exists)
		if err != nil {
			fmt.Println("Error checking ai existence:", err)
			return
		}

		if exists {
			//当前对局存在ai玩家，进行下一步判断，判断ai是否已经死亡,如果ai玩家没有死亡则将其他玩家的发言信息储存起来
			survival := 0
			err = handle.QueryRow("SELECT Survival FROM player WHERE Role =1 AND RmNo = ?", rm).Scan(&survival)
			if err != nil {
				fmt.Println("Error checking ai survival:", err)
			}
			if survival == 1 && speaking != 1 { //ai存活且当前讲话的玩家不是ai玩家
				if speaktype == 1 {
					handle.Exec("INSERT INTO  player_speech (RmNo, PlayerInt,Speech) VALUES (?,?,?)", rm, speaking, content)
				} else if speaktype == 2 {
					success := otherPlayersLastWords(rm, speaking, content) //告知ai发言信息
					if !success {
						fmt.Println("Error informing ai of last words")
					}
					//遗言发表处理
				}
			}

		}
		broadcastMessage(fmt.Sprintf("玩家%d发言: %s", user, content), "Speak")
	}

}

func broadcastMessage(message, ty string) {
	mu.Lock()
	defer mu.Unlock()

	response := struct {
		Msg  string `json:"msg"`
		Type string `json:"type"`
	}{Msg: message, Type: ty}

	jsonResponse, err := json.Marshal(response)
	if err != nil {
		fmt.Println("Error marshaling response:", err)
		return
	}

	for client := range clients {
		err := client.WriteMessage(websocket.TextMessage, []byte(jsonResponse))
		if err != nil {
			fmt.Println("Error sending message:", err)
			client.Close()
			delete(clients, client) // Remove client on error
		}
	}
}
